<?php
/**
 * @author: justwkj
 * @date: 2021/8/6 16:14
 * @email: justwkj@gmail.com
 * @desc:
 */

namespace app\common\service;

use app\common\constants\PublicConstant;
use think\Db;
use think\Exception;

class OrderService {


    /**
     * 创建订单
     * @param $identity 身份
     * @param $user_id 用户id
     * @return int|string 订单id
     * @author: justwkj
     * @date: 2021/8/6 16:25
     */
    private static function createOrder($identity, $user_id,$order_sdk) {

        //查询是否有未支付的订单,有则返回订单号以及订单金额.没有就创建新的订单
        //如果同时使用JSAPI和H5或者更多支付,订单需要分类 比如 order_sdk=JSAPI

        //查询是否有未支付的订单,不存在则创建
        $existsOrder = (new \app\common\model\Order())->where([
            'user_id' => $user_id,
            'identity' => $identity,
            'order_sdk' => $order_sdk,//JSAPI H5
        ])->where('status', '<>', PublicConstant::PAYSTAUS_YES)->order('id asc')->find();
        if ($existsOrder) {
            return [
                'order_no' => $existsOrder->getData('order_no'),
                'amount' => $existsOrder->getData('amount'),
            ];
        }

        //订单金额元
        $amount = 20;
        $order_no = self::buildOrderNo($identity);
        (new \app\common\model\Order())->insertGetId([
            'user_id' => $user_id,
            'identity' => $identity,
            'order_no' => $order_no,
            'order_sdk' => $order_sdk,
            'create_time' => time(),
            'amount' => $amount, //元
        ]);
        return [
            'order_no' => $order_no,
            'amount' => $amount,
        ];

    }

    /**
     * 生成订单编号
     * @param $identity
     * @return string
     * @author: justwkj
     * @date: 2021/8/6 16:25
     */
    private static function buildOrderNo($identity) {
        return vsprintf('%s%s%s', [
            $identity,
            date('YmdHis'),
            rand(1000, 9999)
        ]);
    }


    /**
     * 获取H5支付链接
     * @param $identity
     * @param $user_id
     * @return false|mixed
     * @author: justwkj
     * @date: 2021/8/6 16:30
     */
    public static function getH5PayUrl($identity, $user_id, $order_sdk='H5') {
        $orderData = self::createOrder($identity, $user_id, $order_sdk);
        //支付金额转换
        $payUrl = (new \app\common\library\WechatPay())->h5($orderData['order_no'], $orderData['amount'] * 100);
        return $payUrl;
    }

    /**
     * jsapi支付
     * @param $identity
     * @param $user_id
     * @param $openid
     * @param string $order_sdk
     * @return array|mixed
     * @author: justwkj
     * @date: 2021/8/26 22:19
     */
    public static function getJsApi($identity, $user_id, $openid, $order_sdk='JSAPI') {
        $orderData = self::createOrder($identity, $user_id, $order_sdk);
        writeLog('$orderData', 'wxpay');
        writeLog($orderData, 'wxpay');
        //支付金额转换
        return  (new \app\common\library\WechatPay())->jssapi($orderData['order_no'], $orderData['amount'] * 100, $openid);
    }

    /**
     * 智能获取支付链接
     * @param $identify
     * @param $user_id
     * @return false|mixed|string
     * @author: justwkj
     * @date: 2021/8/26 22:08
     */
    public static function getSmartPayUrl($identify, $user_id) {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) { //微信客户端 jsapi支付
            $url = 'http://' . $_SERVER['HTTP_HOST'] . '/wap/Index/pay?identity=' . $identify . '&user_id=' . $user_id;
        } else { //h5支付
            $url = self::getH5PayUrl($identify, $user_id);
        }
        return $url;
    }


    /**
     * 微信支付成功回调处理
     * @param $data
     * @return bool
     * @author: justwkj
     * @date: 2021/8/6 17:06
     */
    public static function callbackHandle($data) {
        $order_no = $data['out_trade_no'];
        $trade_no = $data['transaction_id'];
        $amount = $data['total_fee']; //订单金额

        //查询订单是否存在
        $orderModel = new Order();
        $order = $orderModel->where('order_no', $order_no)->find();
        if (!$order) {
            throw new \Exception('订单不存在');
        }
        if ($order->getData('amount') * 100 != $amount) {
            throw new \Exception('回调参数有误!');
        }

        if ($order->getData('status') == PublicConstant::PAYSTAUS_YES) { //支付成功
            return true;
        }


        Db::startTrans();
        try {
            //更新业务逻辑 ..更新订单

            //更新订单
            $order->save([
                'callback' => json_encode($data),
                'callback_time' => time(),
                'update_time' => time(),
                'trade_no' => $trade_no,
                'payed' => $amount / 100,
                'status' => PublicConstant::PAYSTAUS_YES,
            ]);
            Db::commit();
        } catch (Exception $exception) {
            throw new \Exception($exception->getMessage());
            Db::rollback();
        }

        return true;
    }
}